package cn.wps.sdk.demo.util;

import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.text.TextUtils;

import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;

public class FileUtil {

    private static final int IO_BUFFER_SIZE	= 8192;


    public static String getFileName(String filePath)
    {
        if (null == filePath)
            return null;
        return new File(filePath).getName();
    }

    /**
     *
     * @param uri 文件uri
     * @param fileDir 沙盒目录 files/fileDir
     * @return 沙盒路径
     */
    public static String copyFileFromUri(Context context, Uri uri, String fileDir) {
        File dirFile = getFileDir(context, fileDir);
        String fileName = parseFileName(context, uri);
        String destPath = dirFile.getAbsolutePath() + File.separator + fileName;
        if (new File(destPath).exists()) {
            new File(destPath).deleteOnExit();

        }
        InputStream inputStream = null;
        try {
            inputStream = context.getContentResolver().openInputStream(uri);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
        if (copyFile(inputStream, destPath)) {
            return destPath;
        }
        return null;
    }

    public static boolean copyFile(InputStream in, String destPath)
    {
        return copyFile(in, destPath, true);
    }

    public static boolean copyFile(InputStream in, String destPath, boolean closeInput)
    {
        if (in == null || destPath == null)
            return false;

        File outFile = new File(destPath);

        if (!prepareFilePath(outFile))
            return false;

        FileOutputStream os = null;
        try
        {
            os = new FileOutputStream(outFile);
            copy(in, os);
            return true;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            closeQuietly(os);
            if (closeInput) closeQuietly(in);
        }
        return false;
    }

    public static void copy(InputStream in, OutputStream out) throws IOException
    {
        copy(in, out, null);
    }

    public static void copy(InputStream in, OutputStream out, byte[] buffer) throws IOException
    {
        if (null == buffer)
            buffer = new byte[IO_BUFFER_SIZE];
        int read;
        while ((read = in.read(buffer)) != -1)
        {
            out.write(buffer, 0, read);
        }
    }

    private static boolean prepareFilePath(File file)
    {
        File parent = file.getParentFile();
        assert parent != null;
        if (parent.exists()) {
            return true;
        }
        return parent.mkdirs();
    }

    public static void closeQuietly(FileOutputStream out)
    {
        if (null == out)
            return;
        try {
            out.flush();
            try {
                out.getFD().sync(); // bug 314867
            } catch (Exception ignore) {
            }
            out.close();
        } catch (IOException ignore)
        {
        }
    }

    public static void closeQuietly(Closeable closable)
    {
        if (null == closable)
            return;
        try {
            if (closable instanceof FileOutputStream)
            {
                FileOutputStream _out = (FileOutputStream)closable;
                _out.flush();
                try {
                    _out.getFD().sync();
                } catch (Exception ignore) {
                }
            }
            else if (closable instanceof RandomAccessFile)
            {
                RandomAccessFile _out = (RandomAccessFile)closable;
                try {
                    _out.getFD().sync();
                } catch (Exception ignore) {
                }
            }
            closable.close();
        } catch (IOException ignore)
        {
        }
    }

    private static String parseFileName(Context context, Uri uri) {
        if (ContentResolver.SCHEME_FILE.equals(uri.getScheme())) {
            return StringUtil.getNamePart(uri.getPath());
        }
        String name = queryDisplayName(context, uri);
        if (!TextUtils.isEmpty(name)) {
            return name;
        }
        name = queryOtherColumn(context, uri);
        if (!TextUtils.isEmpty(name)) {
            return name;
        }

        if (TextUtils.isEmpty(name)) {
            String urlPath = uri.getPath();
            String namePart = StringUtil.getNamePart(urlPath);
            String extPart = StringUtil.pathExtension(urlPath);
            if (!TextUtils.isEmpty(namePart) && !TextUtils.isEmpty(extPart)) {
                name = namePart;
            }
        }
        return name;
    }

    private static String queryDisplayName(Context context, Uri uri) {
        ContentResolver resolver = context.getContentResolver();
        Cursor cur = null;
        String name = null;
        try {
            cur = resolver.query(uri, new String[]{MediaStore.MediaColumns.DISPLAY_NAME}, null, null, null);
            if (cur != null && cur.getCount() == 1 && cur.moveToFirst()) {
                final int displayNameIndex = cur.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME);
                if (displayNameIndex != -1) {
                    String displayName = cur.getString(displayNameIndex);
                    if (!TextUtils.isEmpty(displayName)) {
                        String namePart =StringUtil.getNamePart(displayName);
                        String ext = StringUtil.pathExtension(displayName);
                        if (!TextUtils.isEmpty(namePart) && !TextUtils.isEmpty(ext)) {
                            name = displayName.trim();
                        }
                    }
                }
            }
        } catch (Exception ignore) {
        } finally {
            if (cur != null) {
                cur.close();
            }
        }
        return name;
    }

    private static String queryOtherColumn(Context context, Uri uri) {
        ContentResolver resolver = context.getContentResolver();
        Cursor cur = null;
        String name = null;
        try {
            cur = resolver.query(uri, null, null, null, null);
            if (cur != null && cur.getCount() == 1 && cur.moveToFirst()) {
                if (TextUtils.isEmpty(name)) {
                    int fileNameIndex = cur.getColumnIndex("file_name");
                    if (fileNameIndex != -1) {
                        String fileName = cur.getString(fileNameIndex);
                        if (!TextUtils.isEmpty(fileName)) {
                            name = fileName;
                        }
                    }
                }
                if (TextUtils.isEmpty(name)) {
                    int dataIndex = cur.getColumnIndex(MediaStore.MediaColumns.DATA);
                    if (dataIndex != -1) {
                        String dataPath = cur.getString(dataIndex);
                        if (!TextUtils.isEmpty(dataPath)) {
                            name = new File(dataPath).getName();
                        }
                    }
                }
            }
        } catch (Exception ignore) {
        } finally {
            if (cur != null) {
                cur.close();
            }
        }
        return name;
    }

    public static File getFileDir(Context context, String fileDir) {
        File file = context.getExternalFilesDir(fileDir);
        if (!file.exists()) {
            boolean result = file.mkdirs();
            if (!result) {
                throw new RuntimeException("create file dir fail");
            }
        }
        return file;
    }
}
